# **怎么写出一个skill**
> 本文方法论提炼自艾笑AI《<span style="color: rgba(0, 0, 0, 0.9);">**写skill懵逼必看，从简单到复杂skill的工程化指南**</span>》，原文发布于 2026 年 7 月 21 日。   

# 写 skill 懵逼必看，从简单到复杂 skill 的工程化指南
> 很多人写 Skill，第一反应是把自己知道的东西全塞进去。结果不是 AI 更会干活，而是它更会卡住。   

现在写 Skill，越来越少人一个字一个字敲。你把需求丢给 AI，它十几秒就吐出一个 SKILL.md。问题也恰恰在这里：AI 很会写，但它不会替你做架构决策。你不懂 Skill 的工程规则，它就照着你给的坏样例，把 Skill 越堆越厚——就像不懂软件工程的人让 AI 疯狂写代码，最后得到一座谁也不敢动的屎山，改一行怕塌，想复用没法拆。

所以这篇文章的重点不是"怎么写出一个 Skill"，而是"怎么像管代码工厂一样管 Skill"：让公共能力沉淀到一处、让业务差异各自隔离、让每一次修改都是加一块积木而不是糊一层补丁。可维护性，以及始终保持简洁、优雅的架构，才是简单 Skill 和商业级 Skill 真正的分水岭。

![](./assets/001_7a09baac-803a-43b5-a555-f92ff6892bf4.jpg)

## 01 Skill 不是提示词，是可安装的工作单元

如果你只是想让 AI 写一段文案，提示词就够了。

但如果你希望 AI 每次都按同一套流程处理文件、调用脚本、读取资料、停在人审节点、最后产出稳定结果，那就不再是提示词问题，而是 Skill 工程问题。

一个好的 Skill，本质上像一份很短的上岗手册。它告诉 Agent：什么时候该使用我，输入是什么，输出是什么，哪些事情必须停下来等人确认，哪些事情交给脚本做，哪些资料只有需要时再读。

坏的 Skill 则像一份越来越厚的事故备忘录。今天失败一次，就补一段"千万不要"；明天跑偏一次，再补一段"绝对禁止"；后天卡住一次，又加三条红线。最后它看起来很严谨，实际上已经变成上下文黑洞。

真正要做的不是继续加规则，而是问一句：这件事应该由 LLM 判断，还是应该由工程结构保证？

![](./assets/002_fa689ce1-6d35-4980-9151-a3d359190c5e.jpg)

## 02 官方规范的核心：渐进披露

官方 Skill 结构并不复杂。

最小形态就是一个文件夹，里面有一个 SKILL.md。这个文件必须有 name 和 description，正文写这个 Skill 怎么用。

复杂一点，可以增加三个目录：
```text
skill-name/
  SKILL.md
  scripts/
  references/
  assets/
```

SKILL.md 负责最小入口。

scripts/ 放确定性强、重复执行、容易出错的动作。比如路径解析、日期判断、文件校验、网页抓取、状态机推进。

references/ 放需要读进上下文的参考资料。比如风格规范、字段说明、案例示例、领域知识。

assets/ 放要被使用但不必读进上下文的素材。比如模板文件、字体、图片、示例工程。

这里有个关键原则：Agent 一开始只需要知道这个 Skill 是否该触发，不需要一次读完所有细节。

所以 description 要写清楚触发场景，SKILL.md 要短，详细内容拆到 references，确定性流程交给 scripts。

这就叫渐进披露。

![](./assets/003_1601555c-a2ea-4808-9e8e-34c6cb2e5287.jpg)

## 03 简单 Skill 怎么写

简单 Skill 通常只做一件事。

比如"把一篇 Markdown 文章改成某种排版风格"。这种 Skill 的职责应该很窄：
- 输入：一篇 Markdown。
- 输出：原地排版后的 Markdown。
- 停止点：找不到文件、用户没确认是否覆盖。
- 禁止项：不改正文事实、不上传、不发布。

这类 Skill 的 SKILL.md 可以很短。它不需要写一大段行业背景，也不需要讲十种历史事故。

最好的写法是：

第一，description 里直接写触发词和边界。
第二，正文只写流程。
第三，模板规则放 references。
第四，如果排版规则很稳定，就写脚本；如果需要审美判断，就让 LLM 执行，但要给清晰 checklist。

简单 Skill 最怕"顺手扩展"。本来只排版，后来又想顺手起标题、顺手同步平台、顺手生成封面。每多一个"顺手"，就多一个失败面。

![](./assets/004_fcb569b6-f192-41a8-a5a0-f0b2f026bf44.jpg)

## 04 复杂 Skill 不是把多个 Skill 写进一个大文档

复杂 Skill 常见于自动化生产流程。以我自己开发的「图片工厂」为例。

平时我会让 AI 帮我做很多种图：公众号正文配图、公众号封面、视频封面缩略图、知识卡片、营销活动海报……它们表面上都是"生成一张 PNG"，于是最偷懒的写法，就是塞进一个巨型 SKILL.md——把五种业务的规则、七八套模板、付费 API 调用、图片校验，全糊在一起。

看起来一键化，实际最危险。因为每种业务的输入结构、模板菜谱、生成后处理其实都不一样：
- 知识卡片是竖版、要系列感、右下角还得做入口后处理；
- 封面要突出标题、走横版；
- 正文配图要贴合段落语义；
- 海报要按转化文案排版。

把这些差异全塞进同一段自然语言，AI 每改一次都可能踩到别的业务。

于是很多人会走向另一个极端：每来一种图，就单独写一个 skill——做封面一个、做卡片一个、做海报一个，各自注册成全局技能。刚开始很爽，因为每个都短小干净。但很快就会撞上两个问题。

一是 skill 越堆越多。光图片这条线就能拆出五六个，再加上写文、排版、同步……全局技能列表很快膨胀成几十个。

二是 基础配置根本没法复用。付费 API 怎么调、凭证边界、"默认 dry-run、显式确认才付费"的门禁、图片存哪、路径怎么解析——这些每个业务都要用的东西，你得在每个独立 skill 里重抄一遍。改一次调用方式，就要改五六个地方，漏一个就出 bug。

更隐蔽的坑，是注册和调用会打架。

我之前装过一套挺流行的第三方 skill 合集，它也号称"主 skill \+ 子 skill"分层，但主 skill 和一堆子 skill 全被单独注册到了全局。结果 agent 每次要路由，都在一堆描述高度相似的技能之间反复犹豫，注册和调用相互重复，有几次直接把执行卡死——你看着它转圈好几分钟，一个字都不出。

这不是模型笨，是工程化没做清楚：谁是入口、谁只能被内部调用、谁根本不该出现在全局列表里，全是糊的。

所以真正的解法，既不是一个几百行的巨型 SKILL.md，也不是摊一地各自为政的独立 skill，而是"一个安装入口，内部分层路由"。放到一起当然更复杂，但这份复杂度是被组织过的——关键就在于职责怎么切。

具体到图片工厂，它长这样：
```text
image-factory/
  scripts/
　　generate_image_asset.py      # 通用生图引擎(所有业务共用)
　　image_route_map.json         # 业务→薄壳→模板 的路由数据真源
  skills/
　　image-factory/               # 唯一注册成全局的入口
　　  SKILL.md                   #   只写:路由表 + 通用契约
　　  references/                #   凭证 / 产物分级 / 路由 SOP
　　article-illustration-factory/  # 薄壳:正文配图
　　  SKILL.md
　　  templates/
　　cover-factory/               # 薄壳:封面 / 缩略图 / 首图
　　  SKILL.md
　　  templates/                 #   每种封面风格一个 JSON
　　knowledge-card-factory/      # 薄壳:知识卡片
　　  SKILL.md
　　  scripts/                   #   卡片专属后处理
　　  templates/
　　poster-factory/              # 薄壳:营销 / 活动海报
　　  SKILL.md
　　  templates/
```

目录结构清楚了，那 SKILL.md 本身长什么样？下面是主入口 image-factory 的最小骨架。你写第一个 skill 时可以从下面这份复制起手，不用啃官方文档：
```markdown
---
name: image-factory
description: 生成图片素材的唯一入口。用户说「给这篇配图」/「做张封面」/「批量生图」时派我。内部路由到 article-illustration / cover / knowledge-card / poster 薄壳,不直接干活。
tools: Read, Write, Bash
---

你是 image-factory 入口 skill。**不直接生图,只做路由**。

## 触发时机
- 「给这篇文章配图」
- 「做张 <平台名> 封面」
- 「批量生图」

## 工作流
1. 识别用户想要的图片类型 → 路由到对应薄壳
2. 派 subagent 或调 Bash 脚本
3. 输出到 assets/ 下按日期归档

## 铁律
- ❌ 不许直接调 Write HTML + 截图(那是 text-to-visual 的活)
- ❌ 不许自己生 PNG,必须走 ai-router MCP
- ✅ 默认 dry-run,加 `--apply` 才真调 API
```

这份骨架 3 分钟能填完、跑得起来。跑通之后再往里长复杂逻辑——路由表配置化、状态机、lint 校验，一步步加。结构本身就是给 AI 的护栏，骨架越薄，AI 帮你扩展时越不容易堆屎山。

只有 image-factory 一个东西注册成全局技能。用户说"做张封面""做组知识卡片""照这张海报做"，都先进这个入口；入口读一张路由表，把请求分发到对应的业务薄壳。四个薄壳不单独注册，只能通过主入口内部调用。

![](./assets/005_f2ac6a9c-d34c-4155-a5ba-18e99ac503f0.jpg)

关键在于职责怎么切：

**通用能力只写一处。** 凭证边界、"默认 dry-run、加 --apply 才调付费 API"的门禁、产物分级、图片是否真实生成的校验、路径约定——这些所有业务都要遵守的规矩，只写在主入口。薄壳里明确标注一句"通用规范全部见主 skill，本文件不再重复"。

**业务差异隔离在各自薄壳。** 知识卡片薄壳只写卡片专属的 brief 字段、模板菜谱和后处理；海报薄壳只写海报那一套。它们互不 import、互不知道对方存在，改一个不会波及另一个。

**加新东西是加文件，不是改核心。** 想加一种新封面风格？在 cover-factory/templates/ 丢一个新的模板 JSON。想加一整条新业务线？加一个薄壳目录、在路由表里加一行。那个所有业务共用的生图引擎，一个字都不用动。

这套结构和代码工程里的"工厂化"是同一回事：公共逻辑下沉、业务实现隔离、用一张配置表把它们连起来。它比安装五个各自为政的独立 Skill 更好路由，也比一个几百行的巨型 SKILL.md 更稳、更好改。

更关键的是：当我让 AI 帮我扩展它时，AI 有明确的"该往哪放"的规则可循——新模板进 templates、新业务加薄壳、公共规则进主入口——而不是无脑往主文档里继续堆。架构本身，就是给 AI 的护栏。结构越清晰，AI 代写时越不容易堆出屎山。

## 05 哪些事情该交给脚本，哪些事情该交给 LLM

Skill 最容易出问题的地方，其实不是写得不够详细，而是业务流跑不稳——同样的输入，这次对了、下次错了，你永远不知道它会在哪一步飘。

根子上是一个认知错位：很多人把 Skill 当成"更长的提示词"，以为把要求写得够细、约束够多，AI 就一定照做。但一个 Skill 里其实混着三类完全不同的活——有的该交给 LLM 判断，有的该交给脚本执行，有的该走 MCP 或外部工具调用。把它们全丢给 LLM 用自然语言"约束"，就是不稳定的起点。

做过 Coze（或任何工作流平台）的人对这点会很有共鸣：一个纯 prompt 节点，你把提示词写到天上去，它也没法保证 100% 稳定输出；真正让流程稳下来的，是把确定性的步骤拆成独立的工作流节点——判断、取数、调 API、格式校验，各归各位。Skill 是同一个道理，只不过节点从可视化拖拽，换成了脚本、MCP 调用和 LLM 步骤的分工。

所以第一步不是"把提示词写得更狠"，而是先分清：这一步到底该谁干。

判断标准很简单：只要答案应该稳定，就不要交给 LLM 猜。

![](./assets/006_74eed9ea-59d6-4759-ab5e-5e941896fa11.png)

**适合脚本的事情：**
- 日期解析；
- 路径解析；
- 文件是否存在；
- JSON/YAML 校验；
- URL 抽取；
- 网页抓取；
- 状态推进；
- dry-run/apply；
- 字数统计；
- 图片文件是否真实生成；
- 重复项检测。

**适合 LLM 的事情：**
- 写作；
- 归纳；
- 风格改写；
- 信息分组；
- 判断一个案例对用户意味着什么；
- 给复杂材料起标题；
- 在多个合理方案里做取舍。

中间有一类混合任务：比如"给一篇长文配图"。画面画什么、贴合哪个段落、走什么调性，这是审美判断，交给 LLM；但用哪套模板、图片尺寸多少、调哪个 provider、是不是真的生成了 PNG、有没有误触发付费，这些必须由脚本和门禁保证。

也就是说，LLM 可以负责表达和审美，但确定性的边界要由结构化流程约束。

如果 AI 声称"图已生成"，实际却没有文件落盘，不应该继续给 Skill 加一句"不要谎报已生成"。正确做法是：让脚本在生成后做真实性校验，没有 PNG 就明确报错，让付费只能由命令行显式 --apply 触发。

## 06 Skill 验收不能只看"跑通了"

一个 Skill 跑通一次，不代表它可用。

我现在更倾向用八项检查来验收：

**第一，单一职责。** 这个 Skill 到底只做一件事，还是偷偷做了三件事？如果一个 Skill 同时写稿、抓取、发布、同步，还没有状态机，那一定会变脆。

**第二，按需加载。** name、description、正文和 references 是否分清楚？是不是把所有细节都塞进了 SKILL.md？

**第三，可预测。** 输入是什么，输出是什么，文件落在哪里，失败时停在哪里，有没有明确示例？

**第四，可容错。** 空输入、路径不存在、抓取失败、用户只说"OK"、外部服务超时，这些情况会发生什么？有没有人审断点？

**第五，可扩展。** 稳定流程和变化细节是否分开？新增一种模板、一个渠道、一个 provider，是改配置还是重写主 Skill？

**第六，跨对话记忆。** 状态是否落到文件里？还是全靠上一轮聊天记忆？只靠聊天记忆的流程，换个会话就断。

举个我自己 image-factory 的状态文件作参考——落 manifest.yaml，和 skill 同目录，每次调用读写：
```yaml
# image-factory/manifest.yaml — 跨会话状态
current_task: article-illustration
stage: sample_generated          # planned → sampled → generated → inserted → uploaded
planned_slots: 5                 # plan 阶段计算出的插图数
generated_slots: 5
inserted_slots: 3                # 已完成插入
uploaded_slots: 0
last_run_at: 2026-07-02 22:15:30
source_article: "[[<文章路径>]]"
```

每个 skill 的字段设计不同，但关键是有 `stage` 字段跟状态机 next 状态对齐——换会话打开 skill，第一件事读 manifest.yaml，根据 stage 决定"接着做什么"，不问用户"上次跑到哪了"。

**第七，踩坑点。** 有没有把最容易误解的边界写清楚？注意这里不是写事故长文，而是写对执行有帮助的短规则。

**第八，禁止清单。** 有没有明确"不做什么"？比如不默认发布、不默认写库、不代替用户审核、不凭标题补事实。

这八项的价值，是把"我感觉它可以"变成"它真的有可验证边界"。

![](./assets/007_0d692ac1-8555-4f10-8f1d-98075dec2ba9.jpg)

## 07 个人用、团队用、商业用，要求完全不同

个人 Skill 可以粗糙一点。只要你自己知道怎么触发，失败了能手动救回来，哪怕写得口语化也能用。

团队 Skill 就不能这样。团队里有不同的人、不同 Agent、不同项目。Skill 必须让第一次接手的人也知道怎么跑，出错时知道停在哪里，改动时知道影响范围。

商业 Skill 和个人 / 团队 Skill 的分水岭，不在于"更严格"，而在于要面对跨会话 / 跨 Agent / 跨用户三重不确定性，展开说两条：

**① 低上下文占用 —— SKILL.md description 必须能被 Agent"扫一眼就懂"**

商业场景下你的 Skill 会跟另外几十个 Skill 一起被 Agent 扫描。每个 Skill 的 description 决定 Agent 是否派你。如果你的 description 是长文，Agent 会在"没读完不敢选"这一层就把你跳过去了。

做法就是在 description 留三件事——「触发词 \+ 一句话干什么 \+ 边界」；背景、例子、原理全挪到正文和 references。不是"写得越详细越好"，而是"Agent 一眼能不能判断这是不是它要找的"。

**② regression case 落在仓库里 —— 不是"跑一遍就好"**

个人 Skill 你自己跑一次通过就算能用。商业 Skill 不行——你今天改一个字段，下一版可能就把某个老用户的流程挂掉，而你不知道。

做法：仓库里建一个 tests/fixtures/ 存 3-5 个历史真实调用场景的输入 \+ 期望输出。改 Skill 前后各跑一次 python3 scripts/regression.py，输出差异 diff。人肉审：这是我改出来的、想要的差异，还是意外破坏了老行为？

这一条我踩过三次才加进来。前两次都是"看似小改，结果老用户跑不通"，事后花几倍时间救。

其他几项，比如明确版本 / 稳定 contract / 自动化 lint / 安装边界 / 凭证边界 / 错误报告 / 用户审核节点——每一条都能单独展开，不赘述了。底层逻辑是同一个：凡是"跨用户跨会话时可能不一致"的地方，都要把不确定性变成结构。

这时 Skill 已经不是"提示词资产"，而是产品的一部分。

![](./assets/008_55a47679-7909-431e-a2f7-8c85674c7aed.jpg)

## 08 最常见的坑

**第一个坑，是把事故复盘写进主入口。** 复盘应该进 ADR、handoff 或 postmortem，主 Skill 只保留执行需要知道的结论。

**第二个坑，是父 Skill 解释子 Skill 的内部实现。** 父 Skill 应该只说"下一步调用谁、输入输出是什么"。子 Skill 内部怎么做，由子 Skill 自己负责。

**第三个坑，是把审核写成自然语言。** "用户确认后再执行"不够。真正可靠的是状态文件、--user-reviewed 参数或显式 approved flag。

**第四个坑，是所有 Skill 都装全局。** Skill 不是越多越强。全局 Skill 太多，会增加路由成本，也会让 Agent 在相似描述之间犹豫。

**第五个坑，是把脚本能做的事交给 LLM。** 日期、路径、文件、状态、URL、超时，这些都应该工程化。LLM 的强项是理解和表达，不是当文件系统。

![](./assets/009_bd5f4ba5-87c7-4efd-a3ed-4831c541fb5b.jpg)

## 09 写在最后：门槛已经变了

Skill 好写，AI 十几秒就能给你一个。但"能跑一次"和"能一直稳、能一直改、能给别人用"之间，隔着的正是工程化这道坎。

逻辑其实很简单：简单 Skill 守住单一职责、别顺手扩展；复杂 Skill 别写成巨型文档、也别摊成一地独立 skill，而是一个入口、内部分层、公共能力只写一处；而贯穿始终的那条主线，是分清哪一步该交给 LLM、哪一步该交给脚本和 MCP，把不该猜的东西变成结构，而不是靠不断加提醒去硬扛。

过去大家焦虑的是"我不会写 Skill"，但这件事的门槛正在飞快归零——你不会写，AI 替你写。

于是分水岭悄悄换了位置：从"你会不会用 AI 写 Skill"，变成了"当 AI 帮你把 Skill 越写越多、越改越复杂时，你有没有一套工程化的规矩，让它始终简洁、优雅、可维护"。

![](./assets/010_9735bf0e-e15b-4ea8-9bd7-4d786d904190.jpg)

懂工程的人，Skill 会变成越用越顺的资产；不懂的人，迟早被自己那堆屎山反噬——就像不懂软件工程的人让 AI 狂写代码，最后代码没人敢碰。

所以从今天起，别再一失败就往主文档里堆提醒。每写一步，先停下来问两句：
- 这一步该谁干（LLM、脚本，还是 MCP）？
- 这块东西该放哪（主入口、薄壳，还是配置）？

把这两个问题问顺了，你的 Skill 就会从"越改越厚"变成"越改越薄"。


